package org.ricks.game.hotfix;

import java.lang.classfile.ClassFile;
import java.lang.classfile.ClassModel;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 热修复管理器 - 使用类加载器隔离策略
 */
public class HotfixManager {
    private static final ReentrantLock LOCK = new ReentrantLock();
    private static final HotfixClassLoader HOTFIX_CLASS_LOADER = new HotfixClassLoader();
    private static final Map<String, Class<?>> HOTFIX_CLASSES = new ConcurrentHashMap<>();

    public static ReentrantLock getLock() {
        return LOCK;
    }

    /**
     * 解析类名
     */
    public static String parseClassName(byte[] classBytes) {
        ClassFile cf = ClassFile.of();
        ClassModel model = cf.parse(classBytes);
        String internalName = model.thisClass().name().stringValue();
        return internalName.replace('/', '.');
    }

    /**
     * 使用类加载器隔离策略热更类
     */
    public static Class<?> hotfixClass(byte[] classBytes) {
        String className = parseClassName(classBytes);

        // 使用自定义类加载器加载新类
        Class<?> newClass = HOTFIX_CLASS_LOADER.loadClass(classBytes, className);

        // 缓存热更类
        HOTFIX_CLASSES.put(className, newClass);

        return newClass;
    }

    /**
     * 获取热更后的类（如果存在）
     */
    public static Class<?> getHotfixClass(String className) {
        return HOTFIX_CLASSES.get(className);
    }

    /**
     * 热更类加载器
     */
    static class HotfixClassLoader extends ClassLoader {
        public HotfixClassLoader() {
            super(Thread.currentThread().getContextClassLoader());
        }

        public Class<?> loadClass(byte[] classBytes, String className) {
            try {
                // 首先检查是否已加载
                Class<?> loadedClass = findLoadedClass(className);
                if (loadedClass != null) {
                    return loadedClass;
                }

                // 定义新类
                return defineClass(className, classBytes, 0, classBytes.length);
            } catch (Exception e) {
                throw new RuntimeException("加载热更类失败: " + className, e);
            }
        }
    }
}
